﻿using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using TMPro;
using Unity.VisualScripting;

public class PathfindingDebugStepVisual : MonoBehaviour
{
    public static PathfindingDebugStepVisual Instance { get; private set; }

    //方块预制体
    [SerializeField] Transform PathFindingDebugObject;
    List<Transform> nodeList;
    Transform[,] nodeArray;

    //每个文本物体的事件
    List<GridSnapshotAction> nodeActionList;

    public void Awake()
    { 
        Instance = this;
        nodeList = new List<Transform>();
        nodeActionList = new List<GridSnapshotAction>();
    }

    public void SetUp(Grid<PathNode> g)
    {
        nodeArray = new Transform[g.GetWidth(), g.GetHeight()];
        
        for(int i=0;i<g.GetWidth();i++)
        { 
            for(int j=0;j<g.GetHeight();j++)
            {
                Vector3 pos = new Vector3(i, j) * g.GetCellSize() + Vector3.one * g.GetCellSize() * 0.5f;
                Transform node = CreateVisualNode(pos);
                node.Find("Node").localScale = Vector3.one*(g.GetCellSize()-1);
                nodeArray[i, j] = node;
                nodeList.Add(node);
            }
        }
        //隐藏全部数字方块
        HideNode();
    }


    public Transform CreateVisualNode(Vector3 pos)
    {
        return Instantiate(PathFindingDebugObject, pos, Quaternion.identity);
    }

    public void HideNode()
    {
        foreach (Transform temp in nodeList)
        {
            SetUpVisualNode(temp, 99999, 99999, 99999);
        }
    }

    public void SetUpVisualNode(Transform obj,int gCost,int hCost,int fCost)
    {
        if (fCost < 1000)
        {
            obj.GetComponent<PathNodeText>().SetCost(gCost, hCost, fCost);
        }
        else
        {
            obj.GetComponent<PathNodeText>().Initialize();
        }
    }

    //清除所有物体文本事件
    public void ClearSnapshot()
    {
        nodeActionList.Clear();
    }

    //每一步的事件
    public void TakeSnapshot(Grid<PathNode> g,PathNode current,List<PathNode> openList,List<PathNode> closeList)
    {
        GridSnapshotAction curAllAction = new GridSnapshotAction();
        curAllAction.AddAction(HideNode);  //先将所有文本节点都隐藏，以便后续变更颜色的操作

        for (int i = 0; i < g.GetWidth(); i++)
        {
            for (int j = 0; j < g.GetHeight(); j++)
            { 
                PathNode node = g.GetGridObject(i, j);

                if (!node.isWalkable) continue;


                int gCost = node.gCost;
                int hCost = node.hCost;
                int fCost = node.fCost;

                bool isCurNode = node == current;
                bool isOpenNode = openList.Contains(node);
                bool isCloseNode = closeList.Contains(node);
                int tempX = i;
                int tempY = j;

                curAllAction.AddAction(() =>
                {
                    Transform nodeText = nodeArray[tempX, tempY];
                    SetUpVisualNode(nodeText, gCost, hCost, fCost);
                    Color backGroundColor = MyUtility.GetColorFromString("636363");

                    if (isCurNode)
                    {
                        backGroundColor = new Color(0, 1, 0);
                    }
                    else if (isOpenNode)
                    {
                        backGroundColor = MyUtility.GetColorFromString("009AFF");
                    }
                    else if (isCloseNode)
                    {
                        backGroundColor = new Color(1, 0, 0);
                    }
                    nodeText.GetComponent<PathNodeText>().ChangeColor(backGroundColor);
                });
            }
        }

        nodeActionList.Add(curAllAction);
    }

    public void TakeFinalSnapshot(Grid<PathNode> g, List<PathNode> path)
    {
        GridSnapshotAction curAllAction = new GridSnapshotAction();
        curAllAction.AddAction(HideNode);  //先将所有文本节点都隐藏，以便后续变更颜色的操作

        for (int i = 0; i < g.GetWidth(); i++)
        {
            for (int j = 0; j < g.GetHeight(); j++)
            {
                PathNode node = g.GetGridObject(i, j);

                if (!node.isWalkable) continue;


                int gCost = node.gCost;
                int hCost = node.hCost;
                int fCost = node.fCost;

                bool isPathNode = path.Contains(node);
                int tempX = i;
                int tempY = j;

                curAllAction.AddAction(() =>
                {
                    Transform nodeText = nodeArray[tempX, tempY];
                    SetUpVisualNode(nodeText, gCost, hCost, fCost);
                    Color backGroundColor = MyUtility.GetColorFromString("636363");

                    if (isPathNode)
                    {
                        backGroundColor = new Color(0, 1, 0);
                    }
                    else 
                    {
                        backGroundColor = MyUtility.GetColorFromString("636363");
                    }

                    nodeText.GetComponent<PathNodeText>().ChangeColor(backGroundColor);
                });
            }
        }

        nodeActionList.Add(curAllAction);
    }

    public void BlockGrid(Grid<PathNode> g)
    {
        //shouldCloseGrid = true;

        for (int i = 0; i < g.GetWidth(); i++)
        {
            for (int j = 0; j < g.GetHeight(); j++)
            {
                PathNode node = g.GetGridObject(i, j);

                Transform nodeText = nodeArray[i, j];
                Color backGroundColor = MyUtility.GetColorFromString("636363");
                if (node.isWalkable)
                {
                    backGroundColor = MyUtility.GetColorFromString("636363");
                }
                else
                {
                    backGroundColor = new Color(0, 0, 0);
                }
                nodeText.GetComponent<PathNodeText>().ChangeColor(backGroundColor);
            }
        }
    }


    public void ShowNextSnapshot()
    { 
        if(GetActionListCount() > 0) 
        {
            nodeActionList[0].TriggerAction();
            nodeActionList.RemoveAt(0);
        }
    }

    public int GetActionListCount()
    {
        return nodeActionList.Count;
    }    
}
